package com.sitech.ibnms.util.remoteControl.impl;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TelnetNotificationHandler;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
import org.apache.log4j.Logger;

import com.sitech.ibnms.util.remoteControl.RemoteController;

public class TelnetThread implements RemoteController {

	private TelnetClient tc = null;
	private OutputStream outstr = null;
	private InputStream instr = null;
	private boolean autorized = false;
	private String host_ip = null;
	private int host_port = 23;
	private String login_id = null;
	private String password = null;
	private String keywords = "bomcagent";
	String RPCCMD = "";
	private StringBuffer result = new StringBuffer();
	private boolean endExecute = false;

	private Logger logger = Logger.getLogger("COLL");
	
	/**
	 * 判断指定关键字的进程是否存在
	 * @return
	 */
	public boolean isRunning(String keywords) {
		this.keywords = keywords;
		this.doCommand("ps -ef | grep " + this.keywords);
		String result = this.getResult();
		result = result.replaceAll("grep " + this.keywords, " ");
		if (result != null && result.indexOf(this.keywords) != -1) {
			return true;
		} else {
			return false;
		}

	}

	public void setRPCCMD(String rpccmd) {
		RPCCMD = rpccmd;
	}

	/**
	 * 
	 * @param host_ip
	 * @param port
	 * @param login_id
	 * @param password
	 */
	public TelnetThread(String host_ip, int port, String login_id,
			String password) {
		this.host_ip = host_ip;
		this.host_port = port;
		this.login_id = login_id;
		// this.password = DES3.decrypt(password);
		this.password = password;
	}

	/**
	 * ��¼����
	 * 
	 */
	public void initial() {
		try {
			tc = new TelnetClient();
			TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
			EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
			SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);
			try {
				tc.addOptionHandler(ttopt);
				tc.addOptionHandler(echoopt);
				tc.addOptionHandler(gaopt);
			} catch (InvalidTelnetOptionException e) {
				System.err.println("Error registering option handlers: " + e.getMessage());
			}
			tc.connect(this.host_ip, this.host_port);
			// tc.registerNotifHandler(new
			// TelnetThread(this.host_ip,this.host_port, this.login_id,
			// this.password));
			tc.setSoTimeout(120000);

			outstr = tc.getOutputStream();
			instr = tc.getInputStream();
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}

		int login_times = 0;
		String s = this.getResult();
		System.out.println("输入账号前：" + s);
		while ((s.endsWith("login: ") || s.endsWith("Password: ")) && tc.isConnected()) {
			if (s.endsWith("login: ")) {
				this.doCommand(this.login_id);
				s = this.getResult();
				System.out.println("输入账号后：" + s);
				login_times += 1;
				if (login_times > 2) {
					System.out.println("�û������������󣡣���");
					this.autorized = false;
					try {
						tc.disconnect();
						// System.exit(0);
//						return;
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}

			if (s.endsWith("Password: ") || s.endsWith("Password:")) {
				this.doCommand(this.password);
				s = this.getResult();
				System.out.println("输入密码后：" + s);
			}
		}
		this.autorized = true;

	}

	public void doCommand(String command) {
		if (tc == null || !tc.isConnected()) {
			return;
		}
		if (this.endExecute == false) {
			return;
		}
		if (this.outstr == null) {
			return;
		}
		String shell = "";
		if (!command.endsWith("\n")) {
			shell += command + "\n";
		} else {
			shell += command;
		}
		try {
			this.result = new StringBuffer();
			this.endExecute = false;
			outstr.write(shell.getBytes());
			outstr.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String getResult() {
		if (tc == null || !tc.isConnected()) {
			return null;
		}
		if (instr == null) {
			return null;
		}
		if (this.endExecute == true) {
			return null;
		}

		try {

			byte[] buff = new byte[1024];
			char[] chabuff = new char[1024];
			int ret_read = 0;
			InputStreamReader inr = new InputStreamReader(instr);
			do {
				ret_read = inr.read(chabuff);
				if (ret_read > 0) {
					String ss = new String(chabuff, 0, ret_read);
					this.result.append(ss);
					String rs = result.toString().toString();
					if (rs.endsWith(">") || rs.endsWith("$")
							|| rs.endsWith("]") || rs.endsWith(">")
							|| rs.endsWith("$ ")
							|| result.toString().endsWith("login: ")
							|| result.toString().endsWith("Password: ")
							|| result.toString().endsWith("Password:")) {
						break;
					}

				}
			} while (ret_read >= 0);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
		this.endExecute = true;
		return this.result.toString();
	}

	public void receivedNegotiation(int negotiation_code, int option_code) {
		String command = null;
		if (negotiation_code == TelnetNotificationHandler.RECEIVED_DO) {
			command = "DO";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_DONT) {
			command = "DONT";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WILL) {
			command = "WILL";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WONT) {
			command = "WONT";
		}
	}

	public void run() {
		this.initial();
		try {

			byte[] buff = new byte[1024];
			int ret_read = 0;
			do {
				ret_read = System.in.read(buff);
				if (ret_read > 0) {
					if (new String(buff, 0, ret_read).startsWith("quit")) {
						tc.disconnect();
						return;
					} else {
						System.out.println("#" + new String(buff, 0, ret_read)
								+ "#");
					}
					this.doCommand(new String(buff, 0, ret_read));
					this.getResult();
				}
			} while (ret_read > 0);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * �ر�l��
	 * 
	 */
	public void close() {
		try {
			byte b = 0x03;
			outstr.write(b);
			outstr.flush();
			this.doCommand("exit");

			if (tc != null && tc.isConnected())
				tc.disconnect();

			tc = null;
			System.out.println("Disonnection successed!");
		} catch (Exception e) {
			e.printStackTrace();

			try {
				tc.disconnect();
			} catch (Exception e1) {
				e1.printStackTrace();
			}

		}

	}

	public boolean isAuthorized() {
		return this.autorized;
	}

	public boolean isExistDir(String dir) {
		boolean success = true;
		this.doCommand("cd " + dir);

		if (this.getResult().indexOf(dir + ":  not found") != -1) {
			success = false;
		}
		return success;
	}

	public boolean getResultAsString(String targetString) {
		if (tc == null || !tc.isConnected()) {
			return false;
		}
		if (instr == null) {
			return false;
		}
		if (this.endExecute == true) {
			return false;
		}

		try {

			byte[] buff = new byte[1024];
			char[] chabuff = new char[1024];
			int ret_read = 0;
			InputStreamReader inr = new InputStreamReader(instr);
			do {
				ret_read = inr.read(chabuff);
				if (ret_read > 0) {
					String ss = new String(chabuff, 0, ret_read);
					this.result.append(ss);
					String rs = result.toString().toString();
					if (rs.endsWith(">") || rs.endsWith("$")
							|| rs.endsWith("]") || rs.endsWith(">")
							|| rs.endsWith("$ ")
							|| result.toString().endsWith("login: ")
							|| result.toString().endsWith("Password: ")) {
						break;
					}

				}
			} while (ret_read >= 0);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
		this.endExecute = true;
		if (this.result.toString().indexOf(targetString) != -1) {
			return true;
		} else {
			return false;
		}

	}

	public int childCountOfDir(String dir) {
		int count = 0;
		try {
			if (this.isExistDir(dir)) {
				doCommand("cd " + dir + ";ls -l | wc -l");
				String s = null;
				s = getResult();
				String[] s1 = s.split("\n");
				if (s1 != null) {
					count = new Integer(s1[1].trim()).intValue() - 1;
				}
			} else {
				return -1;
			}

		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
		return count;
	}

	public boolean createDir(String dir) {
		boolean isExist = false;
		if (dir != null && !dir.trim().equals("") && this.isExistDir(dir)) {
			isExist = true;
		}
		if (dir != null && !dir.trim().equals("") && !this.isExistDir(dir)) {
			String[] split_dir = dir.split("/");
			for (int i = 0; i < split_dir.length; i++) {
				String path = "";
				for (int j = 0; j <= i; j++) {
					if (split_dir[j] != null && !split_dir[j].equals("")) {
						path += "/" + split_dir[j];
					}
				}

				if (path != null && !path.equals("")) {
					if (!this.isExistDir(path)) {
						this.doCommand("mkdir " + path);
						this.getResult();
					}
					if (!this.isExistDir(path)) {
						return false;
					}
				}
			}
			if (this.isExistDir(dir)) {
				isExist = true;
			}
		}
		return isExist;
	}

	public String getHostName() {
		this.doCommand("hostname");
		String s = null;
		s = getResult();
		String[] s1 = s.split("\n");
		if (s1 != null && s1.length >= 2) {
			// ��ȡ��2��
			if (s1.length == 3)
				return s1[1].trim();
			if (s1.length == 2) {
				return s1[0].trim();
			}
		}
		return "";
	}

	private String getOSType() {
		String os_type = "";
		this.doCommand("uname -a");
		String s = null;
		s = getResult();
		String[] s1 = s.split("\n");
		if (s1 != null && s1.length > 0) {
			String row_1 = s1[0];
			if (row_1 != null && row_1.startsWith("uname -a")) {
				os_type = s1[1];
			} else {
				os_type = s1[0];
			}
			os_type = split(os_type, 0);
		}
		return os_type;

	}

	public String split(String str, int pos) {
		StringTokenizer st = new StringTokenizer(str);
		Vector values = new Vector();
		while (st.hasMoreTokens()) {
			values.add(st.nextToken());
		}
		if (pos >= 0 && pos < values.size()) {
			return (String) values.elementAt(pos);
		}
		return "";
	}

	public Vector getResultAsVector(String command) {
		Vector vResult = new Vector();
		this.doCommand(command);
		String strResult = this.getResult();
		if (strResult != null) {
			String[] results = strResult.split("\n");
			int length = results.length - 1;
			if (results.length > 2) {
				String mail = (String) results[results.length - 2];
				if (mail.indexOf("have mail in") > -1) {
					length = results.length - 2;
				}
			}
			int begin = 0;
			if (getOSType().equals("AIX")) {
				begin = 0;
			} else if (getOSType().equals("HP-UX")) {
				begin = 1;
			}
			for (int i = begin; i < length; i++) {
				vResult.addElement(results[i]);
				System.out.println(i + " " + results[i]);
			}
		}

		return vResult;
	}

	public String getResultAsStr(String command) throws Exception {
		String result = "";
		Vector vResult = new Vector();
		logger.info("Command is " + command);
		this.doCommand(command);
		String strResult = this.getResult();
		if (strResult != null) {
			String[] results = strResult.split("\n");
			int length = results.length - 1;
			if (results.length > 2) {
				String mail = (String) results[results.length - 2];
				if (mail.indexOf("have mail in") > -1) {
					length = results.length - 2;
				}
			}
			int begin = 0;
			if (getOSType().equals("AIX")) {
				begin = 0;
			} else if (getOSType().equals("HP-UX")) {
				begin = 1;
			}
			for (int i = begin; i < length; i++) {
				if (results[i].indexOf(command) > -1)
					continue;
				vResult.addElement(results[i]);
			}
		}
		for (int i = 0; i < vResult.size(); i++) {
			if (i < vResult.size() - 1)
				result += (String) vResult.elementAt(i) + "\n";
			else
				result += (String) vResult.elementAt(i);
		}
		if (result != null && result.endsWith("\r")) {
			result = result.substring(0, result.length() - 1);
		}
		return result.trim();
	}

}
